import { parseHTML } from "./parser.js";
import { generate } from "./generator.js";

// 编译模板的步骤
// 如果调用的时候有render函数，直接走编译
// 拿到template结构【字符串】，编译render函数
// 1、parseHTML 编译出AST语法树 【正则匹配】
//   将AST进行优化
//      优化的目标：生成模板AST，检测不需要进行DOM改变的静态子树。
//   一旦检测到这些静态树，我们就能做以下这些事情：
//      1.把它们变成常数，这样我们就再也不需要每次重新渲染时创建新的节点了。
//      2.在patch的过程中直接跳过。
// 2、generate编译出可执行的函数字符串 【遍历语法树，进行字符串拼接】
// 3、使用with包裹【拼接字符串】
// 4、new Function把字符串变成可执行函数

const AST = {
  type: "div",
  attrs: {
    style: {
      color: "red",
    },
  },
  event: {
    click: () => {},
  },
};

export function compileToFunctions(template) {
  console.log(template);
  // 实现模板的编译
  let ast = parseHTML(template); // '<div></div>'
  console.log(ast);
  //   把任何语言都可以抓化成一个对象

  // ast语法树

  // 代码生成
  // template => render 函数
  /**
   * react
   * render(){
   * with(this){
   *  return _c('div',{id:app,style:{color:red}},_c('span',undefined,_v("helloworld"+_s(msg)) ))
   * }
   * }
   *
   */
  // _c("div",{id:"app"},_c("div",{v-model:"23"},_v(""+_s(msg.name)+""+_s(count)+""+_s(arr[0].name)+""+_s(msg.age))))
  //   ast语法树转化成函数调用的形式 >> 还是字符串
  let code = generate(ast); // 代码生成 => 拼接字符串
  console.log(code); // _c('div',{id:app,style:{color:red}},_c('span',undefined,_v("helloworld"+_s(msg))))

  code = `with(this){ \r\nreturn ${code} \r\n}`;

  let render = new Function(code); // 相当于给字符串变成了函数
  // console.log(render)

  // with(this) {name}
  // render函数执行之后的返回值是一个虚拟dom
  return render;
  // 模板编译原理
  // 1.先把我们的代码转化成ast语法树
  // （1）  parser 解析  (正则)
  // 2.标记静态树  （2） 树得遍历标记 markup  只是优化
  // 3.通过ast产生的语法树 生成 代码 =》 render函数  codegen
}

// const data = {
//   name: "黑马",
// };

// with (vm) {
//   const render = `<div>${name}</div>`
// }
